package Modelo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import jxl.Sheet;
import jxl.Workbook;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

import Vista.VistaEspera;
import Vista.VistaPrincipal;
import Vista.VistaResultados;


public class Modelo {
	
	private static Modelo _theInstance;
	private StandardAnalyzer analyzer;
	private Directory index;
	private ScoreDoc[] hits;
	private IndexSearcher searcher;
	private IndexWriter w ;
	private IndexReader reader; 
	private IndexWriterConfig config;
	
	private ArrayList<InfoPelicula> _peliculasRecup;
	
	private static String archivoDestino="sinopsisPeliculas.xls";
	private static int columnaGenero=1;
	private static int columnaTitulo=2;
	private static int columnaDesc=3;
	private static int capacidadArray=300;
	
	public static Modelo getInstance(){
		if(_theInstance==null)
			_theInstance = new Modelo();
		return _theInstance;
	}
	
	private Modelo(){
		 analyzer = new StandardAnalyzer(Version.LUCENE_35);
		 _peliculasRecup = new ArrayList<InfoPelicula>(capacidadArray);
		 crearIndice();
	}
	
	
	
	private void crearIndice() {
		
		try {
		
			index = new RAMDirectory();
			config = new IndexWriterConfig(Version.LUCENE_35, analyzer);
		
		    w = new IndexWriter(index, config);
		    leerArchivoExcel();
		    w.close();
	} catch (IOException e) {
		mostrarMensaje("Error al crear el indice");
		}
		
	}
	private static void addDoc(IndexWriter w, String value) throws IOException {
		    Document doc = new Document();
		    doc.add(new Field("title", value, Field.Store.YES, Field.Index.ANALYZED));
			w.addDocument(doc);
	}
			  
	private void mostrarMensaje(String msg){
		  JOptionPane.showMessageDialog(null, msg);
	}
	
	public void leerArchivoExcel() { 

		try { 
			Workbook archivoExcel = Workbook.getWorkbook(new File( archivoDestino)); 
			
			Sheet hoja = archivoExcel.getSheet(0); 
			int numFilas = hoja.getRows(); 
			String descripcion;

			for (int fila = 0; fila < numFilas; fila++) { // Recorre cada fila de la hoja 
				
					descripcion = hoja.getCell(columnaDesc, fila).getContents();  
					addDoc(w, descripcion);			
			} 
		 
		} catch (Exception ioe) { 
			mostrarMensaje("Error al leer el archivo Excel"+ioe.toString());
		} 

	}
	
	
	public void EjecutarConsulta(String consultaSeleccionada) {

		Query q;
		try {
			q = new QueryParser(Version.LUCENE_35, "title", analyzer).parse(consultaSeleccionada);
		   // 3. search
		    int hitsPerPage = 10;
		    reader= IndexReader.open(index);
		    searcher = new IndexSearcher(reader);
		    TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
		    searcher.search(q, collector);
		    hits = collector.topDocs().scoreDocs;
		    mostrarResultados();
		} catch (ParseException e) {
			mostrarMensaje("Error al parsear la query");
		} catch (IOException e) {
			mostrarMensaje("Error al ejecutar la consulta");
		}
	}
	
	private void mostrarResultados(){
	
		try {
			_peliculasRecup.clear();
			 // 4. display results
			if(hits.length==0) {
            	VistaEspera.getInstance().parar();
				mostrarMensaje("Encontrados " + hits.length + " sugerencias.");
				VistaPrincipal.getInstance().setVisible(true);
			}
			else{
				for(int i=0;i<hits.length;++i) {
				
				  int docId = hits[i].doc;
				  Document d = searcher.doc(docId);
				  String aux=d.get("title");
				  InfoPelicula peli=new InfoPelicula(aux,sacarTitulo(aux),sacarGenero(aux));
				  _peliculasRecup.add(peli);  
				}
				VistaEspera.getInstance().parar();
				VistaResultados.getInstance().setDatos(_peliculasRecup);
				VistaResultados.getInstance().setVisible(true);
				
			}
			} catch (IOException e) {
				mostrarMensaje("Error al acceder al documento");
		}	    
	}
	
	private String sacarGenero(String aux) {
		try { 
			Workbook archivoExcel = Workbook.getWorkbook(new File( archivoDestino)); 
			
			Sheet hoja = archivoExcel.getSheet(0); 
			int numFilas = hoja.getRows(); 
			String genero="";
			int fila = -1; // Recorre cada fila de la hoja 
			boolean encontrado=false;
			while(fila<numFilas&&!encontrado){
				fila++;
				encontrado=hoja.getCell(columnaDesc, fila).getContents().equals(aux);	
					
			} 
			if(encontrado)
				genero=hoja.getCell(columnaGenero, fila).getContents();
		 return genero;
		} catch (Exception ioe) { 
			
			mostrarMensaje("Error al sacar el genero");
			return null;
		} 
	}

	private String sacarTitulo(String aux) {
		try { 
			Workbook archivoExcel = Workbook.getWorkbook(new File( archivoDestino)); 
			
			Sheet hoja = archivoExcel.getSheet(0); 
			int numFilas = hoja.getRows(); 
			String titulo="";
			int fila = -1; // Recorre cada fila de la hoja 
			boolean encontrado=false;
			while(fila<numFilas&&!encontrado){
				fila++;	
				encontrado=hoja.getCell(columnaDesc, fila).getContents().equals(aux);
					
			} 
			if(encontrado)
			titulo=hoja.getCell(columnaTitulo, fila).getContents();
		 return titulo;
		} catch (Exception ioe) { 
			
			mostrarMensaje("Error al sacar el titulo");
			return null;
		} 
	}

	public void cerrar(){
		  try {
			  if(searcher!=null)
				  searcher.close();
		} catch (IOException e) {
			mostrarMensaje("Error al cerrar el buscador");
		}
	}

 
}
